package com.hori3d.rc;

import android.R.integer;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.graphics.drawable.AnimationDrawable;
import android.mtp.MtpStorageInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.StrictMode;
import android.provider.Telephony.CanonicalAddressesColumns;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.text.TextUtils.SimpleStringSplitter;
import android.text.format.Time;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.lang.reflect.Array;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import com.hori3d.rc.R.id;
import com.hori3d.rc.bean.Printer;

import com.hori3d.rc.utils.Logger;
import com.hori3d.rc.utils.Utils;
import com.hori3d.rc.view.SlidingMenu;

public class MainActivity extends BaseActivity implements View.OnClickListener {
	int i = 0;
 

	private SlidingMenu mMenu;
	private MainActivity mContext;

	private RelativeLayout itemStatus, itemMove, itemSpeed, itemFiles, itemCam, itemOption, itemAbout, itemQuit;
	private TextView titleTV;
	private List<String> titles = Arrays.asList("状态", "移轴", "速度", "文件", "监控", "设置", "关于", "退出");
	ImageView printerConnectedIV, printerDisconnectedIV, printerCommunicatingIV;
	AnimationDrawable anim;
	Handler getFilesHandler;
	ImageButton MenuBtn;

	private Socket socket;
	private PrintStream output;

	boolean isReadingFiles = false;
	ArrayList<String> files = new ArrayList<String>();

	boolean isContected = false;
	boolean gotFirstResponse = false;
	boolean iscommucating = false;
	boolean isRestarting = false;
	boolean isWarming = false;
	ProgressDialog pd1;
	AlertDialog.Builder builder;
	AlertDialog ad;
	public static int MSG_PRINTER_RESPENSE = 100;
	
	
	TimerTask reconnTask=new ReconnectTask();//重新连接任务
	Timer timer = new Timer(); // 定时器 用于执行各种定时查询
	Timer connectTimer= new Timer();//重新连接定时器
	
	
	class QueryTempTask extends TimerTask {

		@Override
		public void run() {
			sendQuery(Printer.CMD_READ_CURRENT_TEMP);
		}
	}

	class QuerySpeedTask extends TimerTask {

		@Override
		public void run() {
			sendQuery(Printer.CMD_READ_CURRENT_SPEED);
		}
	}

	class QueryProcessTask extends TimerTask {

		@Override
		public void run() {
			sendQuery(Printer.CMD_PINTING_PROCESS);
		}
	}
	
	class ReconnectTask extends TimerTask {

		@Override
		public void run() {
			reConnect();
		}
	}


	public void onCreate(Bundle savedInstanceState) {

		mContext = this;
		m3Dprinter = app.getPrinter();
		StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites()
				.detectNetwork().penaltyLog().build());

		super.onCreate(savedInstanceState);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); // 竖屏
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);

	
		mMenu = (SlidingMenu) findViewById(R.id.id_menu);
		mMenu.closeMenu();
		setUpMenu();
		createWarmingDialogBuilder(); // 创建加温提示 对话框

		if (savedInstanceState == null)
			changeFragment(new StastusFragment());
		titleTV.setText(titles.get(0));
        
		// 连接服务器
		initClientSocket();
		timer.schedule(new QueryTempTask(), 3000, 3000);
		timer.schedule(new QuerySpeedTask(), 2000, 3000);
		timer.schedule(new QueryProcessTask(), 1000, 3000);
		connectTimer.schedule(reconnTask,10000,7000);//十秒后自动重连

	}

	void reConnect() {
		Logger.i("重新连接");
	    mHandler.sendEmptyMessage(404);//发送连接失败的消息
		if (socket != null)
			try {
				socket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
      
		if (connPrinterThread != null)
			connPrinterThread.interrupt();
		connPrinterThread=null;
		initClientSocket();
	}

	private void setUpMenu() {
		// 标题栏
		titleTV = (TextView) findViewById(id.tv_title);

		// create menu items;
		itemStatus = (RelativeLayout) findViewById(id.rl_menu_status);
		itemMove = (RelativeLayout) findViewById(id.rl_menu_move);
		itemSpeed = (RelativeLayout) findViewById(id.rl_menu_speed);
		itemFiles = (RelativeLayout) findViewById(id.rl_menu_file);
		itemCam = (RelativeLayout) findViewById(id.rl_menu_cam);
		itemOption = (RelativeLayout) findViewById(id.rl_menu_option);
		itemAbout = (RelativeLayout) findViewById(id.rl_menu_about);
		itemQuit = (RelativeLayout) findViewById(id.rl_menu_quit);

		itemStatus.setOnClickListener(this);
		itemMove.setOnClickListener(this);
		itemSpeed.setOnClickListener(this);
		itemFiles.setOnClickListener(this);
		itemCam.setOnClickListener(this);
		itemOption.setOnClickListener(this);
		itemAbout.setOnClickListener(this);
		itemQuit.setOnClickListener(this);

		// 如果没有设置摄像头，菜单中去掉相关选项
		if (m3Dprinter.getCam_id() == "")
			itemCam.setVisibility(View.GONE);

		MenuBtn = (ImageButton) findViewById(id.title_bar_left_menu);
		MenuBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				mMenu.toggle();
			}
		});
		MenuBtn.getBackground().setAlpha(0);

		/**
		 状态栏右上角  通信状态图标
		**/
		  
		//通讯中： 动画 R.drawable.anim_printer_connect

		printerCommunicatingIV = (ImageView) findViewById(id.iv_title_bar_communicating_state);
		printerCommunicatingIV.setBackgroundResource(R.drawable.anim_printer_connect);
		anim = (AnimationDrawable) printerCommunicatingIV.getBackground();
		anim.stop();
		anim.start();
		
		printerCommunicatingIV.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				new AlertDialog.Builder(ctx).setMessage("打印机通讯正常").show();
			}
		});

		
		//已连接：printerConnectedIV
		printerConnectedIV = (ImageView) findViewById(id.iv_title_bar_contected_state);
		printerConnectedIV.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				new AlertDialog.Builder(ctx).setMessage(m3Dprinter.getPingResult()).show();

			}
		});

		//未连接：printerConnectedIV，初始时显示
		printerDisconnectedIV = (ImageView) findViewById(id.iv_title_bar_discontected_state);
		printerDisconnectedIV.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				new AlertDialog.Builder(ctx).setMessage("无法连接到打印机：请检查打印机ip和端口配置").show();

			}
		});

		
		
		
	}

	/**
	 * 创建 加温提示对话框
	 */
	private void createWarmingDialogBuilder() {
		//
		AlertDialog.Builder builder = new Builder(MainActivity.this);
		builder.setMessage("正在加温，打印即将开始…");
		builder.setTitle("提示");
		builder.setCancelable(false);
		ad = builder.create();

	}

	/**
	 * 画面加载完毕后，开始动画
	 */
	@Override
	public void onWindowFocusChanged(boolean hasFocus) {
		// TODO Auto-generated method stub
		super.onWindowFocusChanged(hasFocus);
		anim.start(); // 打印机网络状态动画

	}

	@Override
	public void onClick(View view) {

		// 当菜单关闭时，不响应点击事件
		if (!mMenu.isOpen())
			return;

		int tag = Integer.valueOf((String) view.getTag());
		// mainActiviy标题栏修改标题
		titleTV.setText(titles.get(tag - 1));

		switch (tag) {
		case 1:
			changeFragment(new StastusFragment());
			break;
		case 2:
			changeFragment(new MoveFragment());
			break;
		case 3:
			changeFragment(new SpeedFragment());
			break;
		case 4:
			changeFragment(new FileFragment());
			break;
		case 5:
			changeFragment(new CameraFragment());
			break;
		case 6:
			changeFragment(new OptionFragment());
			break;
		case 7:
			changeFragment(new AboutFragment());
			break;
		case 8:

			AlertDialog.Builder builder = new AlertDialog.Builder(ctx).setTitle("提示").setMessage("确定要退出应用程序么？")
					.setNegativeButton("确认", new android.content.DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							System.exit(0);
						}
					}).setPositiveButton("取消", new android.content.DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							dialog.dismiss();
						}
					});

			builder.show();

			break;
		default:
			break;
		}

		mMenu.closeMenu();
	}

	public void changeFragment(Fragment targetFragment) {
		// resideMenu.clearIgnoredViewList();

		getSupportFragmentManager().beginTransaction().replace(R.id.main_fragment2, targetFragment, "fragment")
				// .setTransitionStyle(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
				.commit();
	}

	// What good method is to access resideMenu 锛�
	public SlidingMenu getResideMenu() {
		return mMenu;
	}

	Handler mHandler = new Handler() {// 更新界面的显示（不能直接在线程中更新视图，因为Android线程是安全的） {
		public void handleMessage(Message msg) {
			// Logger.i(mStrMSG);
			super.handleMessage(msg);

			switch (msg.what) {
			case 100: // 打印机回应信息
                isContected=true;
				// 第一次收到信息时
				if (!gotFirstResponse) {
					// Utils.toast(ctx, "打印机通讯正常");// 提示通信正常
					sendQuery(Printer.CMD_READ_PRINTER_FIRMWARE);// 查询固件版本指令													// 查询打印机固件版本
					sendQuery(Printer.CMD_GET_SD_FILES);// 获SD卡文件列表 作为初始化列表
					gotFirstResponse = true;
				}

				iscommucating = true;
				
				//重新连接定时器
				reconnTask.cancel();//取消上一次倒计时重连任务
				reconnTask=new ReconnectTask();//重新实例化
				connectTimer.schedule(reconnTask, 7000, 10000); // 重新schedule任务，七秒之后如果没有回应就重连，十七秒后第二次重连

				// 设置状态图标
				printerCommunicatingIV.setVisibility(View.VISIBLE);
				printerConnectedIV.setVisibility(View.GONE);
				printerDisconnectedIV.setVisibility(View.GONE);

				// 将获取信息传递给解析器
				String printerRes = msg.getData().getString("content");
				ResponsePraser(printerRes);

				break;
			case 402: // 打印机网络连接错误

				Utils.toast(mContext, "连接打印机异常,请检查网络");
				isContected = false;
				break;

			case 401: // 发送指令失败
				if (iscommucating)
					Utils.toast(mContext, "发送指令失败");
				break;
 

			case 404: // 连接已断开
				printerCommunicatingIV.setVisibility(View.GONE);
				printerConnectedIV.setVisibility(View.GONE);
				printerDisconnectedIV.setVisibility(View.VISIBLE);
				isContected = false;
				break;

			case 101: // 建已建立连接
				printerCommunicatingIV.setVisibility(View.GONE);
				printerConnectedIV.setVisibility(View.VISIBLE);
				printerDisconnectedIV.setVisibility(View.GONE);

				String pingResult = msg.getData().getString("pingResult");
				m3Dprinter.setPingResult(pingResult);
				break;

		 
			default:
				break;
			}
		}
	};

	private Thread connPrinterThread;

	public void setGetSDFilesHandler(Handler handler) {
		getFilesHandler = handler;
	}

	public void initClientSocket() {
		gotFirstResponse = false;
		connPrinterThread = new Thread() {

			BufferedReader mBufferedReader2;

			public void run() {
			
				Log.i("leo", "连接次数" + (i++));

				try {
					/* 连接服务器 */

					socket = new Socket();
					SocketAddress sa = new InetSocketAddress(m3Dprinter.getPRINTER_IP(), m3Dprinter.getPRINTER_PORT());
					socket.connect(sa, 3000);
					mHandler.sendEmptyMessage(101);//发送已连接消息  
					/* 获取输出流 */
					output = new PrintStream(socket.getOutputStream(), true, "utf-8");
					InputStreamReader mInputStreamReader = new InputStreamReader(socket.getInputStream());
					mBufferedReader2 = new BufferedReader(mInputStreamReader);
				} catch (UnknownHostException e) {
					handleException(e, "unknown host exception: " + e.toString());
				}

				catch (IOException e) {
					handleException(e, "io exception: " + e.toString());
				}

				while (!isInterrupted()) {

					try {
						String tempString = null;
						if ((tempString = mBufferedReader2.readLine()) != null) {
							Message msg = new Message();
							msg.what = 100;// 消息类型为 打印机回应消息
							Bundle bundle = new Bundle();
							bundle.putCharSequence("content", tempString);
							msg.setData(bundle);
							mHandler.sendMessage(msg);
							this.wait(100);
						}
					} catch (Exception e) {
						// Logger.e("eorrow" + e.toString());
					}
				}

			}
		};
		connPrinterThread.start();
	}

	public void closeSocket() {
		try {
			output.close();
			socket.close();
		} catch (IOException e) {
			handleException(e, "close exception: ");
		}
		connPrinterThread.interrupt();
		 
	}

	public void handleException(Exception e, String prefix) {

		Message msg = mHandler.obtainMessage(402);
		mHandler.sendMessage(msg);
		e.printStackTrace();
		Logger.e(prefix + e.toString());
	}

	public void sendQuery(String cmd) {
		if (cmd != "" && cmd != null)
			try {
				output.print(cmd + "\r");
			} catch (Exception a) {
				mHandler.sendEmptyMessage(401);
				Log.e("leo", "发送失败");
			}
	}

	// 打印机response 解析
	void ResponsePraser(String respString) {
		// Logger.i("解析器获得数据"+resString);

		// 加温解析
		if (((respString.contains("T:") && respString.contains("W:"))
				|| (respString.contains("T:") && respString.contains("B:")))) //
		{
			if (!isWarming) { // Utils.toast("正在加温");
				isWarming = true;
				m3Dprinter.setPrinterStatusCode(Printer.PRINTER_STATUS_WARMING); // 判定当前为加温状态
				ad.show(); // 打开对话框
			}

		} else if (isWarming) {
			m3Dprinter.setPrinterStatusCode(Printer.PRINTER_STATUS_NULL); // 不是加温状态
			ad.dismiss();
			Utils.toast("加温完成");
			isWarming = false;

		}

		// 速度解析
		if (respString.contains("ok Speed:")) {
			String subString = respString.substring(9);// 截取字符串
			String[] trueSpeedData = subString.split("\\|");// "|"拆分字符串
			m3Dprinter.setSpeedFans(Integer.parseInt(trueSpeedData[1]));
			m3Dprinter.setSpeedPrint(Integer.parseInt(trueSpeedData[0]));
			m3Dprinter.setSpeedMaterial(Integer.parseInt(trueSpeedData[2]));

			// 温度解析
		} else if (respString.contains("ok Temp:")) {
			// Temp:喷头1当前温度|喷头1目标温度|喷头2当前温度|喷头2目标温度|热床当前温度|热床目标温度
			String subString = respString.substring(8);
			// Logger.i("获得温度原始数据"+subString);
			String[] trueTempData = subString.split("\\|");
			m3Dprinter.setTemp1((int) Double.parseDouble(trueTempData[0]));
			m3Dprinter.setTemp1Target((int) Double.parseDouble(trueTempData[1]));
			m3Dprinter.setTemp2((int) Double.parseDouble(trueTempData[2]));
			m3Dprinter.setTemp2Target((int) Double.parseDouble(trueTempData[3]));
			m3Dprinter.setTempBed((int) Double.parseDouble(trueTempData[4]));
			m3Dprinter.setTempBedTarget((int) Double.parseDouble(trueTempData[5]));

			// 打印机状态解析
		} else if (respString.contains("ok Print:"))
		// ok Print:-1|-1|-1
		{
			String subString = respString.substring(9);
			String[] truePrintData = subString.split("\\|");
			m3Dprinter.setPrinterStatusCode(Integer.valueOf(truePrintData[0]));
			m3Dprinter.setPrintingTime(Integer.valueOf(truePrintData[1]));
			m3Dprinter.setPrintingProcess(Integer.valueOf(truePrintData[2]));
			m3Dprinter.setPrintingFile(truePrintData[3]);

			if (truePrintData[4].equals("1"))
				m3Dprinter.setAutoPowerOff(true);
			else
				m3Dprinter.setAutoPowerOff(false);
		}

		// 打印机固件版本号
		else if (respString.contains("ok Firmware:"))
		// ok Print:-1|-1|-1
		{
			gotFirstResponse = true;
			String subString = respString.substring(12);
			m3Dprinter.setFirmwareVersion(subString);

		}

		// 解析文件列表
		if (isReadingFiles) {
			if (respString.contains("End file list")) {
				isReadingFiles = false;
				m3Dprinter.setFiles(files);
				if (getFilesHandler != null)
				{
					Message m = new Message();
					getFilesHandler.sendMessage(m);
				}
				Log.i("leo", "文件结束" + m3Dprinter.getFiles().size());
			} else {
				files.add(respString);
			}
		} else {
			if (respString.contains("Begin file list")) // 开始读文件目录
			{
				files.clear();// 
				isReadingFiles = true; // 标记正在读文件
				Log.i("leo", "开始接受文件");
			}
		}
	}

	// 当加温状态时 拦截按键事件事件
	public boolean dispatchKeyEvent(android.view.KeyEvent event) {
		if ((m3Dprinter.getPrinterStatusCode() == Printer.PRINTER_STATUS_WARMING)
				&& (event.getKeyCode() == KeyEvent.KEYCODE_BACK))
			return true;
		else
			return super.dispatchKeyEvent(event);

	}

	// 打印机网络通断检查
	private final boolean pingPrinterIP() {

		String result = null;

		try {
			String ip = m3Dprinter.getPRINTER_IP();//
			Process p = Runtime.getRuntime().exec("ping -c 1 -w 1 " + ip);// ping3次

			InputStream input = p.getInputStream();
			BufferedReader in = new BufferedReader(new InputStreamReader(input));
			StringBuffer stringBuffer = new StringBuffer();
			String content = "";
			while ((content = in.readLine()) != null) {
				stringBuffer.append(content);
			}
			Bundle b = new Bundle();
			b.putString("pingResult",
					"网络情况 ：Ping结果" + Calendar.getInstance().getTime().getHours() + ":"
							+ Calendar.getInstance().getTime().getMinutes() + ":"
							+ Calendar.getInstance().getTime().getSeconds() + "\n" + stringBuffer.toString());

			// Log.i("TTT", "result content : " + stringBuffer.toString());

			// PING的状态
			int status = p.waitFor();
			if (status == 0) {
				result = "successful~";
				return true;
			} else {
				result = "failed~ cannot reach the IP address";
			}
		} catch (IOException e) {
			result = "failed~ IOException";
		} catch (InterruptedException e) {
			result = "failed~ InterruptedException";
		} finally {
			// Log.i("TTT", "result = " + result);
		}
		return false;
	}
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		if(timer!=null)
		timer.cancel();
		if(connectTimer!=null)
			connectTimer.cancel();
	}

}
